package srzy.common

import java.net.InetAddress
import java.lang.reflect.Field
import java.io.File

object Config extends srzy.common.Logging {

  private val fileType = "YAML"

  val inputDir = getValue("root", "config", "InputDir")
  val normalCdrDir = getValue("root", "config", "NormalCdrDir").split(":").toList
  val errCdrDir = getValue("root", "config", "ErrCdrDir").split(":").toList
  val transCdrDir = getValue("root", "config", "TransCdrDir").split(":").toList
  val typeToFileNameMap = getValue("root", "config", "TypeToFileName").split(";")
    .toList.map(x => {
      val t = ("""[\p{Graph}&&[^:]]+""".r findAllIn x).toList
      (t.apply(0), t.apply(1))
    }).toMap
  val typeToCdrMap = CdrFieldParser.parse(Config.getValue("root", "config", "TypeToCdrInt"))
  val updateTaskIdSQL = getItems("UpdateTaskIdSQL").getOrElse(Map())

  logger.debug("inputDir:" + inputDir)
  logger.debug("normalCdrDir:" + normalCdrDir)
  logger.debug("errCdrDir:" + errCdrDir)
  logger.debug("transCdrDir:" + transCdrDir)
  logger.debug("typeToFileNameMap:" + typeToFileNameMap)
  logger.debug("typeToCdrMap:" + typeToCdrMap)
  logger.debug("updateTaskIdSQL:" + updateTaskIdSQL)

  val dirs = List(inputDir) ::: normalCdrDir ::: errCdrDir ::: transCdrDir
  dirs.map(x => {
    if (!new File(x).exists()) {
      logger.error("path:" + x + " not exist!")
      throw new Exception("path:" + x + " not exist!")
    }
  })

  def getValue(seq: String*): String = {
    (fileType match {
      case "YAML" => ConfigYAML.getValue(seq: _*)
      case "XML" => ConfigXML.getValue(seq: _*)
    }) match {
      case Some(v) => v
      case None => throw new Exception("Config:" + seq.mkString(",") + " is not assigned")
    }
  }

  def getItems(x: String): Option[Map[String, String]] = {
    fileType match {
      case "YAML" => ConfigYAML.getItems(x)
      case "XML" => ConfigXML.getItems(x)
    }
  }

  def envMap = {
    (
      Config.getClass.getDeclaredFields.map(_.getName).toList.filter((t: String) => {
        """[^\w]""".r findFirstIn t match {
          case None => true
          case _ => false
        }
      }).filter(x => x matches "[A-Z0-9_]*")
      .map(x => (x, ((x: Field) => {
        x.setAccessible(true)
        x.get(Config).toString()
      })(Config.getClass.getDeclaredField(x))))).toMap
  }
}

trait Config {
  val inputDir = Config.inputDir
  val normalCdrDir = Config.normalCdrDir
  val errCdrDir = Config.errCdrDir
  val transCdrDir = Config.transCdrDir
  val typeToFileNameMap = Config.typeToFileNameMap
  val typeToCdrMap = Config.typeToCdrMap
  val updateTaskIdSQL = Config.updateTaskIdSQL
}